class _SimpleReadStream(object):
    """An very simple input stream wrapper.
    """
    def __init__(self, sequence_object):
        self._input_buffer = sequence_object
        self._index = 0

    @property
    def eof(self):
        return self._index == len(self._input_buffer)
    
    def peek_one(self):
        if not self.eof:
            return self._input_buffer[self._index]
        else:
            return None
    
    def read_one(self):
        if not self.eof:
            atom = self._input_buffer[self._index]
            self._index += 1
            return atom
        else:
            return None

    def unread_one(self, atom):
        if self._index > 0:
            i = self._index - 1
            if atom == self._input_buffer[i]:
                self._index = i


class CharReadStream(_SimpleReadStream):
    """An very simple input stream wrapper.
    peek_one and read_one return a one char string
    """
    def __init__(self, text):
        if not isinstance(text, str) and not isinstance(text, unicode):
            raise ValueError('text is not a string')
        _SimpleReadStream.__init__(self, text)


class ByteReadStream(_SimpleReadStream):
    """An very simple input stream wrapper.
    peek_one and read_one return a byte
    """
    def __init__(self, byte_array):
        if not isinstance(byte_array, bytearray):
            raise ValueError('byte_array is not a bytearray')
        _SimpleReadStream.__init__(self, byte_array)


class StringReadStream(ByteReadStream):
    """An very simple input stream wrapper.
    peek_one and read_one return a byte not a char
    """
    def __init__(self, text, encoding='utf-8'):
        if not isinstance(text, str) and not isinstance(text, unicode):
            raise ValueError('text is not a string or a unicode')
        byte_array = bytearray(text, encoding)
        _SimpleReadStream.__init__(self, byte_array)
